package messages;

import java.security.PrivateKey;
import java.security.PublicKey;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import security.Hash;
import utils.Serialization;
import utils.XmlSerializationUtils;

public class SecureMessage implements Convertible {
	
	private static final long serialVersionUID = 1L;
	
	private Object _object;
	private MessageSignature _messageSignature;

	public SecureMessage() {}
	
	public SecureMessage(Object object, String endpointId, String remoteEndpointId, PrivateKey privateKey){
		_object = object;
		
		String objectString = Serialization.SerializeAsXml(object);
		String hashedString = Hash.getStringHash(objectString);
		
		_messageSignature = new MessageSignature(endpointId, remoteEndpointId, hashedString, privateKey);
	}
	
	public Object getObject() {
		return _object;
	}
	
	public String getTimestamp(){
		return _messageSignature.getTimestamp();
	}
	
	public boolean validateMessage(String lastReceivedMessageTS, String remoteEndpointId, String endpointId, PublicKey remotePublicKey) {
		if(_object == null)
			return false;
		
		String objectString = Serialization.SerializeAsXml(_object);
		String hashedObject = Hash.getStringHash(objectString);
		
		return _messageSignature.validateSignature(hashedObject, remoteEndpointId, endpointId, lastReceivedMessageTS, remotePublicKey);
	}

	public Element convertToCanonic(Document doc) {
		Element el = doc.createElement("SecureMessage");

		if (_object != null) {
			Element childEl = XmlSerializationUtils.getConversionObjectXml(_object, doc);
			el.appendChild(childEl);
		}
		
		if(_messageSignature != null){
			Element childEl = XmlSerializationUtils.getConversionObjectXml(_messageSignature, doc);
			el.appendChild(childEl);
		}		
		
		return el;
	}

	public Object convertFromCanonic(Element el) {
		Element objEl = (Element) el.getChildNodes().item(0);
		_object = XmlSerializationUtils.getConversionXmlObject(objEl);
		
		Element signatureEl = (Element) el.getChildNodes().item(1);
		_messageSignature = (MessageSignature) XmlSerializationUtils.getConversionXmlObject(signatureEl);
		
		return this;
	}
}
